package com.dysm.spring.security.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.authentication.BearerTokenExtractor;
import org.springframework.security.oauth2.provider.authentication.OAuth2AuthenticationManager;
import org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler;
import org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint;
import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;

import javax.annotation.Resource;

@Configuration
@EnableResourceServer
@Order(6)
@EnableGlobalMethodSecurity(securedEnabled = true)
public class WebResourceServerConfig extends ResourceServerConfigurerAdapter {

    @Resource
    private InMemoryTokenStore tokenStore;

    @Resource
    private OAuth2AuthenticationManager webAuthenticationManager;

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        resources.resourceId("security-resource-id")
                .tokenStore(tokenStore)
        .stateless(false)
        .tokenExtractor(new BearerTokenExtractor())
        .authenticationManager(webAuthenticationManager);
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers("/login", "/error", "/oauth/*").permitAll()
                .antMatchers(HttpMethod.GET, "/**").access("#oauth2.hasScope('read')")
                .antMatchers(HttpMethod.POST, "/**").access("#oauth2.hasScope('write')")
                .and()
                .exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler())
                .authenticationEntryPoint(new OAuth2AuthenticationEntryPoint());
        http.headers().addHeaderWriter((request, response) ->
                response.addHeader("Access-Control-Allow-Origin", "*"));
    }
}
